/**
 * 遍历packages目录下的所有包，所package.json中配置有apiBuilderOptions，并且为激活状态，执行构建api
 */

const fs = require('fs')
const dotenv = require('dotenv')
const path = require('path')
const packagesDir = path.resolve(__dirname, '../packages')
const args = require('minimist')(process.argv.slice(2))
const { collectPackages, runParallel } = require('./utils')

let packages = collectPackages(packagesDir)

/**
 * 构建API
 * @param {{path:string,value:Record<string,any>,directory:string}} 包描述
 */
const build = function(package) {
  const pkg = package.value
  const apiBuilderOptions = pkg.apiBuilderOptions
  if (apiBuilderOptions && apiBuilderOptions.outputDir) {
    const packageDirectoryPath = package.path
    // API代码输出目录
    const outDir = path.join(packageDirectoryPath, apiBuilderOptions.outputDir)
    // 环境模式，在默认情况下运行开发模式，在jenkins环境下应传入 "--mode production"
    const envMode = args.mode ? args.mode : 'development'
    const envPath = path.join(packageDirectoryPath, `.env.${envMode}`)
    const envDevelopmentExists = fs.existsSync(envPath)
    if (envDevelopmentExists) {
      /** 读取.env中环境变量 */
      const environments = dotenv.config({ path: envPath }).parsed
      buildApi(
        package.directory,
        environments.VUE_APP_API_SERVICE_URL,
        outDir,
        apiBuilderOptions.includes,
        apiBuilderOptions.excludes
      )
    }
  }
}

/**
 * 根据指定的接口服务地址输出到代码到指定目录下
 * @param {String} directory 要自动构建地址的目录
 * @param {String} serviceUrl 接口定义服务接口地址
 * @param {String} outDir 代码输出目录
 * @param {Object} includes 只生成代码的DTO和API前缀
 * @param {Object} excludes 传入需要忽略生成的DTO和API前缀
 */
const buildApi = (directory, serviceUrl, outDir, includes, excludes) => {
  try {
    const apiBuilderPath = path.resolve(__dirname, '../bin/api-builder/index.js')
    const Builder = require(apiBuilderPath)
    new Builder(directory, serviceUrl, outDir, includes, excludes).build()
  } catch (err) {
    console.error(err)
  }
}

// 若提供了only选项仅仅编译only选项的包
const only = args.only || ''
packages = packages.filter(package => {
  const apiBuilderOptions = package.value.apiBuilderOptions
  if (!apiBuilderOptions) return false
  if (!apiBuilderOptions.active) return false
  const targetName = package.directory
  if (only) {
    if (only == targetName) return true
    else return false
  }
  return true
})

runParallel(require('os').cpus().length, packages, build)
